import { spawn } from 'child_process';
import fs from 'fs';
import path from 'path';

import config from '../../config';

/**
 * 创建存放应用代码的目录
 * @param appId 应用ID
 * @returns Promise<boolean> 是否创建成功
 */
export async function createAppDirectory(appId: string): Promise<boolean> {
  try {
    // 验证项目数据路径是否存在
    await fs.promises.access(config.dataPath, fs.constants.F_OK);

    // 创建存放应用代码的文件夹
    const appPath = path.join(config.dataPath, appId);
    await fs.promises.mkdir(appPath, { recursive: true });

    console.log(`应用文件夹创建成功: ${appPath}`);
    return true;
  } catch (error) {
    console.error('应用文件夹创建失败:', error);
    return false;
  }
}

/**
 * 删除应用文件夹
 * @param appId 应用ID
 * @returns Promise<boolean> 是否删除成功
 */
export async function deleteAppDirectory(appId: string): Promise<boolean> {
  try {
    const appPath = path.join(config.dataPath, appId);

    // 检查文件夹是否存在
    try {
      await fs.promises.access(appPath, fs.constants.F_OK);
    } catch {
      // 文件夹不存在，视为删除成功
      console.log(`应用文件夹不存在，跳过删除: ${appPath}`);
      return true;
    }

    // 递归删除文件夹及其内容
    await fs.promises.rm(appPath, { force: true, recursive: true });
    console.log(`应用文件夹删除成功: ${appPath}`);
    return true;
  } catch (error) {
    console.error('应用文件夹删除失败:', error);
    return false;
  }
}

interface RepoVersion {
  // 提交人
  author: string;
  // 提交时间
  date: string;
  // 提交版本hash
  hash: string;
  // 提交信息
  message: string;
}

type CalcAppRepoVerisonResult = {
  data?: {
    // 本地版本与远程版本的差值
    calcVersion: number;
    // 本地仓库版本信息
    localVersion: RepoVersion;
    // 远程仓库版本信息
    remoteVersion: RepoVersion;
  };
  msg: string;
  success: boolean;
};

/**
 * 计算应用仓库的版本信息
 * @param appId 应用ID
 * @param repoName 仓库名称，如：iotui-dev
 * @return Promise<CalcAppRepoVerisonResult>
 */
export async function calcAppRepoVerison(
  appId: string,
  repoName: string,
): Promise<CalcAppRepoVerisonResult> {
  // 应用数据存储路径
  const appDirectory = path.join(config.dataPath, appId);
  // 检查应用数据存储路径是否存在
  try {
    await fs.promises.access(appDirectory, fs.constants.F_OK);
  } catch (error) {
    return {
      msg: `应用数据存储路径不存在: ${appDirectory}`,
      success: false,
    };
  }
  // 本地仓库路径 = 应用数据存储路径 + repoName
  const localRepoPath = path.join(appDirectory, repoName);
  // 检查本地仓库路径是否存在
  try {
    await fs.promises.access(localRepoPath, fs.constants.F_OK);
  } catch (error) {
    return {
      msg: `本地仓库路径不存在: ${localRepoPath}`,
      success: false,
    };
  }
  // 执行 git 命令获取本地仓库 最新一条提交信息
  const localVersion = getLastComminInfo(localRepoPath)
}

/**
 * 获取本地仓库的最新提交信息
 * @param repoPath 本地仓库路径
 * @return Promise<RepoVersion | null> 最新提交信息，或 null 如果获取失败
 */
async function getLastComminInfo(repoPath: string) {
  return new Promise((resolve, reject) => {
    const git = spawn('git', [
      'log',
      '-1',
      '--pretty=format:%H|%an|%ad|%s',
      '--date=iso',
    ], { cwd: repoPath });

    let output = '';
    git.stdout.on('data', (data) => {
      output += data.toString();
    });

    git.stderr.on('data', (data) => {
      // 可选：可以记录错误日志
    });

    git.on('close', (code) => {
      if (code === 0 && output) {
        const [hash, author, date, ...messageArr] = output.split('|');
        resolve({
          hash,
          author,
          date,
          message: messageArr.join('|'),
        });
      } else {
        resolve(null);
      }
    });

    git.on('error', (err) => {
      reject(err);
    });
  });
}
